﻿using System;
using System.Text;

namespace Isaac.Joy.Identity.Module
{
    /// <summary>
    /// 用于表示权限值标记的结构，支持位运算
    /// </summary>
    public struct FlagsValue
    {
        private readonly string _value;
        public FlagsValue(string value)
            : this()
        {
            value = value ?? "";
            var realvalue = new StringBuilder();
            foreach (var c in value.Trim())
            {
                realvalue.Append(c == '1' ? '1' : '0');
            }
            _value = realvalue.ToString().TrimStart(new[] { '0' });
            if (string.IsNullOrEmpty(_value)) _value = "0";
        }

        public FlagsValue(int index)
            : this()
        {
            var realvalue = new StringBuilder();
            for (var i = 0; i < index; i++)
            {
                realvalue.Insert(0, '0');
            }

            if (index >= 0) realvalue.Insert(0, '1');

            _value = realvalue.ToString();
            if (string.IsNullOrEmpty(_value)) _value = "0";
        }

        /// <summary>
        /// 根据字符串值创建FlagsValue
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static FlagsValue CreateByIds(string value)
        {
            var fvalue = new FlagsValue("0");
            if (string.IsNullOrEmpty(value)) return fvalue;

            var ids = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var idstr in ids)
            {
                int result;
                if (!int.TryParse(idstr, out result)) result = 0;
                fvalue = fvalue | new FlagsValue(result);
            }

            return fvalue;
        }

        /// <summary>
        /// 根据最大index创建允许所有权限的FlagsValue
        /// </summary>
        /// <param name="maxid"></param>
        /// <returns></returns>
        public static FlagsValue CreateAll(int maxid)
        {
            var realvalue = new StringBuilder();
            for (var i = 0; i <= maxid; i++)
            {
                realvalue.Append('1');
            }
            return new FlagsValue(realvalue.ToString());
        }

        /// <summary>
        /// 长度
        /// </summary>
        public int Length
        {
            get { return _value.Length; }
        }

        /// <summary>
        /// 判断某权限是否可用
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public bool Enabled(int index)
        {
            var valueindex = _value.Length - index - 1;
            if (valueindex < 0) return false;

            return _value[valueindex] == '1';
        }

        /// <summary>
        /// 判断某权限是否可用
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public bool Enabled(FlagsValue value)
        {
            return (this & value) == value;
        }

        #region  重载比较算法

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            if (!(obj is FlagsValue)) return false;

            return Equals((FlagsValue)obj);
        }

        public bool Equals(FlagsValue feesValue)
        {
            return _value == feesValue._value;
        }

        public override int GetHashCode()
        {
            return this._value.GetHashCode();
        }

        public static Boolean operator ==(FlagsValue toCompare, FlagsValue compareTo)
        {
            return toCompare.Equals(compareTo);
        }

        public static Boolean operator !=(FlagsValue toCompare, FlagsValue compareTo)
        {
            return !toCompare.Equals(compareTo);
        }

        public static FlagsValue operator &(FlagsValue leftObj, FlagsValue rightObj)
        {
            var result = new StringBuilder();
            for (var i = 0; i < Math.Max(leftObj.Length, rightObj.Length); i++)
            {
                result.Insert(0, leftObj.Enabled(i) && rightObj.Enabled(i) ? '1' : '0');
            }

            return new FlagsValue(result.ToString());
        }

        public static FlagsValue operator |(FlagsValue leftObj, FlagsValue rightObj)
        {
            var result = new StringBuilder();
            for (var i = 0; i < Math.Max(leftObj.Length, rightObj.Length); i++)
            {
                result.Insert(0, leftObj.Enabled(i) || rightObj.Enabled(i) ? '1' : '0');
            }

            return new FlagsValue(result.ToString());
        }

        public static FlagsValue operator ^(FlagsValue leftObj, FlagsValue rightObj)
        {
            var result = new StringBuilder();
            for (var i = 0; i < Math.Max(leftObj.Length, rightObj.Length); i++)
            {
                result.Insert(0, leftObj.Enabled(i) != rightObj.Enabled(i) ? '1' : '0');
            }

            return new FlagsValue(result.ToString());
        }

        #endregion

        #region  重载ToString方法

        public override string ToString()
        {
            return _value;
        }

        #endregion
    }
}
